package com.kgis.fm.business.effects
{
	import com.kgis.map.feature.Feature;
	import com.kgis.map.geometry.ArrowLineGeometry;
	import com.kgis.map.geometry.PointGeometry;
	import com.kgis.map.geometry.PolygonGeometry;
	import com.kgis.map.geometry.PolylineGeometry;
	
	import mx.effects.Tween;
	import mx.effects.effectClasses.TweenEffectInstance;
	
	public class ExtendPolylineEffectInstance extends TweenEffectInstance
	{
		public var pctStart:Number;
		public var pctEnd:Number;
		public var alsoAnimateAlpha:Boolean;
		public var playReverseDirection:Boolean;
		private var _aryTargetPathInfos:Array;
		private var _nTargetTotalLength:Number;
		private var _geomOriginal:PolylineGeometry;
		
		public function ExtendPolylineEffectInstance(feature:Feature)
		{
			super(feature);
		}
		
		override public function set target(param:Object) : void
		{
			
			this._geomOriginal =(param as Feature).geometry as PolylineGeometry;
			super.target = param;
		}
		
		public function gatherPolylineInfo() : void
		{
			
			var pathArray:Array = null;
			var allLen:Number = NaN;
			var p1:PointGeometry = null;
			var p2:PointGeometry = null;
			var len:Number = NaN;
			var polyline:PolylineGeometry = (target as Feature).geometry as PolylineGeometry;
			this._aryTargetPathInfos = [];
			pathArray=[];
			allLen = 0;
			for (var i:int = 1; i < polyline.pointList.length; i++) 
			{
				
				p1 = this.playReverseDirection ? (polyline.pointList[i]) : (polyline.pointList[i-1]);
				p2 = this.playReverseDirection ? (polyline.pointList[i - 1]) : (polyline.pointList[i]);
				len = this.segmentLength(p1, p2);
				pathArray.push({startPoint:p1, endPoint:p2, segmentLength:len});
				allLen = allLen + len;	
				
			}
			if (this.playReverseDirection)
			{
				pathArray.reverse();
			}
			this._aryTargetPathInfos.push({segmentInfos:pathArray, pathLength:allLen});
		}
		
		override public function play() : void
		{
			super.play();
			var tw:Tween = createTween(this, this.pctStart, this.pctEnd, duration);
			
		}
		
		override public function onTweenUpdate(param1:Object) : void
		{
			var pathInfo:Object = null;
			var _loc_6:Number = NaN;
			var _loc_7:Number = NaN;
			var _loc_8:Array = null;
			var _loc_9:int = 0;
			var _loc_10:Object = null;
			var _loc_11:PointGeometry = null;
			var _loc_12:PointGeometry = null;
			var _loc_13:Number = NaN;
			var _loc_14:Number = NaN;
			var _loc_15:Number = NaN;
			var _loc_16:Number = NaN;
			var _loc_17:Number = NaN;
			var _loc_18:PointGeometry = null;
			var _loc_2:* = param1 as Number;
			var feature:Feature = target as Feature;
			var geom:ArrowLineGeometry = new ArrowLineGeometry();
			for each (pathInfo in this._aryTargetPathInfos)
			{
				
				_loc_6 = pathInfo.pathLength * (_loc_2 / 100);
				_loc_7 = 0;
				_loc_8 = [];
				_loc_9 = 0;
				while (_loc_9 < pathInfo.segmentInfos.length)
				{
					
					_loc_10 = pathInfo.segmentInfos[_loc_9];
					_loc_11 = _loc_10.startPoint;
					_loc_12 = _loc_10.endPoint;
					_loc_13 = _loc_10.segmentLength;
					if (_loc_9 == 0)
					{
						geom.pointList.addItem(_loc_10.startPoint);
					}
					if (_loc_7 + _loc_13 < _loc_6)
					{
						geom.pointList.addItem(_loc_12);
						_loc_7 = _loc_7 + _loc_13;
					}
					else
					{
						_loc_14 = _loc_6 - _loc_7;
						_loc_15 = _loc_14 / _loc_13;
						_loc_16 = (_loc_12.x - _loc_11.x) * _loc_15;
						_loc_17 = (_loc_12.y - _loc_11.y) * _loc_15;
						_loc_18 = new PointGeometry(_loc_11.x + _loc_16, _loc_11.y + _loc_17);
						geom.pointList.addItem(_loc_18);
						break;
					}
					_loc_9 = _loc_9 + 1;
				}
				
			}
			feature.geometry = geom;
			if (this.alsoAnimateAlpha)
			{
				feature.alpha = Number(param1) / 100;
			}
			feature.executeDrawing();
		}
		
		override public function onTweenEnd(param:Object) : void
		{
			super.onTweenEnd(param);
			(target as Feature).geometry = this._geomOriginal;
			
		}
		
		private function segmentLength(pt1:PointGeometry, pt2:PointGeometry) : Number
		{
			return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
		}
	}
}